import React, { forwardRef, PureComponent } from 'react'
import {
  AutoComplete,
  Button,
  Col,
  DatePicker,
  Form,
  Input,
  message,
  Popconfirm,
  Popover,
  Radio,
  Row,
  Select,
  Spin,
  Tabs,
  Upload
} from 'antd'
import { connect, withRouter } from '@umijs/max'
import _ from 'lodash'
import moment from 'moment'
import { regExp } from '@/utils/regExp.js'
import Tools from '@/utils/Tools'
import { CreateDiffEditor, ProTable, ProTableOptions } from '@/components'
import { getProjectId, SUAN_PAN } from '@/utils/https'
import styles from './index.less'

const { Item, List } = Form
const { TabPane } = Tabs
const { Option } = Select
const { Dragger } = Upload
const modelStr = `function parseJson(inputParam) {
    // inputParam为返回报文的JSON字符串
    // var dataObj = JSON.parse(inputParam)
    // var result=[['参数1','参数2','...']]  // 定义参数名
    // var 参数1 = dataObj.errno //输入根节点数据
    // for(i=0; i < dataObj.xx.length; i++) {  // 此处输入处理逻辑,以循环遍历为例
    //    var arr = []
    //    var 参数2 = dataObj.xx[0].yy  // 输入叶子节点数据
    //    arr.push(参数1)
    //    arr.push(参数2)
    //    result.push(arr)
    // }
    // return result
  }`

const descRe = regExp.name(2, 32)
const urlRe = regExp.url()
const lenRe = regExp.proName(1, 128)
const urlLenRe = regExp.proName(1, 8182)
const tokenLenRe = regExp.proName(1, 4096)
const Bus = Tools.Bus

// 请求参数位置
const headArr = ['head', 'body', 'query']

// 请求参数中的参数类型
const paramDataTypeArr = ['STRING', 'INT', 'LONG', 'FLOAT', 'DOUBLE', 'BOOLEAN']

const paramProps = [
  { value: 0, label: '无', defaultValue: '' },
  { value: 1, label: 'pageNo', defaultValue: 0 },
  { value: 2, label: 'pageSize', defaultValue: 100 },
]

const EditableCell = ({
  editing,
  dataIndex,
  title,
  inputType,
  record,
  index,
  children,
  ...restProps
}) => {
  let inputNode = null
  if (dataIndex === 'operation') {
    inputNode = inputType(record)
  } else if (dataIndex === 'paramPosition' || dataIndex === 'paramDataType') {
    const listTemp = dataIndex === 'paramPosition' ? headArr : paramDataTypeArr
    inputNode = (
      <Form.Item
        name={dataIndex}
        style={{ margin: 0 }}
        rules={[
          {
            required: true,
            message: `请选择${title}`,
          },
        ]}
      >
        <Select
          allowClear
          showSearch
          filterOption={(input, option) => option.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
          placeholder={`${dataIndex === 'paramPosition' ? '请选择参数位置' : '请选择参数类型'}`}
        >
          {
            listTemp?.map(item => (
              <Option key={item}>{item}</Option>
            ))
          }
        </Select>
      </Form.Item>
    )
  } else if (dataIndex === 'paramAttribute') {
    inputNode = (
      <Form.Item
        name={dataIndex}
        style={{ margin: 0 }}
        rules={[
          {
            required: true,
            message: `请选择${title}`,
          },
        ]}
      >
        <Select placeholder="请选择参数属性">
          {
            paramProps?.map(item => (
              <Option label={item.label} key={item.value} value={item?.value}>{item?.label}</Option>
            ))
          }
        </Select>
      </Form.Item>
    )
  } else {
    inputNode = (
      <Form.Item
        name={dataIndex}
        style={{ margin: 0 }}
        rules={[
          {
            required: true,
            message: `请输入${title}`,
          },
          // {
          //   pattern: new RegExp(lenRe.reg, 'g'),
          //   message: lenRe.text,
          // },
        ]}
      >
        <Input placeholder={`请输入${title}`} />
      </Form.Item>
    )
  }

  let childrenTemp = children
  if (dataIndex === 'paramAttribute') {
    const paramAttributeVal = children?.[1]
    const filterObj = paramProps.filter(item => item.value === paramAttributeVal)
    childrenTemp = filterObj[0]?.label
  }

  return (
    <td {...restProps}>
      {editing ? (
        inputNode
      ) : (
        childrenTemp
      )}
    </td>
  )
}

class DataSource extends PureComponent {
  constructor(props) {
    super(props)
    this.state = {
      headerColumns: [
        {
          title: '参数名称',
          dataIndex: 'paramName',
          width: '15%',
          key: 'paramName',
          editable: true,
        },
        {
          title: '参数位置',
          dataIndex: 'paramPosition',
          width: '15%',
          key: 'paramPosition',
          editable: true,
        },
        {
          title: '参数属性',
          dataIndex: 'paramAttribute',
          width: '15%',
          key: 'paramAttribute',
          editable: true,
        },
        {
          title: '参数类型',
          dataIndex: 'paramDataType',
          width: '15%',
          key: 'paramDataType',
          editable: true,
        },
        {
          title: '参数值',
          dataIndex: 'paramValue',
          width: '15%',
          key: 'paramValue',
          editable: true,
        },
        {
          title: '描述',
          dataIndex: 'paramDesc',
          width: '15%',
          key: 'paramDesc',
          editable: true,
        },
        {
          title: '操作',
          dataIndex: 'operation',
          // width: '30%',
          key: 'operation',
          editable: true,
          inputType: (record) => (
            <ProTableOptions>
              <span onClick={this.onFieldSaveClick}>保存</span>
              {
                // 此处作删除使用
                (!record.paramName || record.paramName === '') ? (
                  <span onClick={() => { this.onDelClick(record) }}>取消</span>
                ) : (
                  <span onClick={this.onFieldCancelClick}>取消</span>
                )
              }
            </ProTableOptions>
          ),
          render: (text, record) => (
            <ProTableOptions>
              {
                this.props?.formData?.isView ? (
                  <>
                    <span className={styles.disabled}>编辑</span>
                    <span className={styles.disabled}>删除</span>
                  </>
                ) : (
                  <>
                    <span onClick={() => this.onEditClick(record)}>编辑</span>
                    <Popconfirm
                      title="你确定要删除这个字段吗？"
                      okText="确定"
                      cancelText="取消"
                      onConfirm={() => this.onDelClick(record)}
                    >
                      <span>
                        删除
                      </span>
                    </Popconfirm>
                  </>
                )
              }
            </ProTableOptions>
          ),
        },
      ],
      editingKey: undefined,
      activeTabKey: '1',
      jsScript: modelStr,
      requestHeaderData: [],
      rawJson: '',
      apiLoading: false,
      fieldSuggestion: [],
      resExampleRawJson: '',
      tableViewLoading: false,
      previewSta: true,
      fileList: [],
      diffEditorUpdate: true,
      responseRawJsonTemp: '',
      previewLoading: false,
    }

    this.editorResonseId = `${Math.random()}`
    this.editorJsEditId = `${Math.random()}`
    this.editorObjectEditId = `${Math.random()}`

    this.dataSourceForm = React.createRef()
    this.tableData = React.createRef()
    this.customEditorRef = React.createRef()
    this.objectParamsRef = React.createRef()
    this.returnRef = React.createRef()
  }

  componentDidMount() {
    // if (id && !formData?.isGoBack) {
    //   // this.viewDetail(id)
    // } else {
    //   this.initParams()
    // }

    this.initParams()
    Bus.addListener('editorLayout', this.handleToggleAside)
  }

  // 根据左侧的伸缩，更新 diffEditor 输入框
  handleToggleAside = () => {
    const bodyRaw = this.objectParamsRef?.current?.getEditorValue() || ''
    const jsScript = this.customEditorRef?.current?.getEditorValue() || modelStr
    const returnCont = this.returnRef?.current?.getEditorValue() || ''
    this.setState((prevSta) => (
      {
        diffEditorUpdate: !prevSta.diffEditorUpdate,
      }
    ), () => {
      setTimeout(() => {
        this.setState((prevSta) => (
          {
            diffEditorUpdate: !prevSta.diffEditorUpdate,
            rawJson: bodyRaw,
            jsScript,
            resExampleRawJson: returnCont,
          }
        ))
      }, 100)
    })
  }

  // 初始化页面参数
  initParams = () => {
    const { formData } = this.props
    const { apiHttpRequest, taskName, previewExpressRequest } = formData || {}
    const {
      httpRequestMethod, url, apiHttpAuthParam, apiHttpRequestHeaderParam, apiHttpRequestBodyParam,
    } = apiHttpRequest || {}
    const { params } = apiHttpRequestHeaderParam || {}
    const { expressionParamList, jsScript, responseRawJson } = previewExpressRequest || {}
    // const requestHeaderData = []
    // params?.map((item, index) => {
    //   requestHeaderData.push({
    //     fieldName: item.name,
    //     fieldValue: item.value,
    //     key: index,
    //   })
    //   return null
    // })

    // const { body = '' } = apiHttpRequestBodyParam || {}
    // this.setState({
    //   requestHeaderData,
    //   rawJson: body,
    // })

    const { body = '', contentType, formParams } = apiHttpRequestBodyParam || {}
    const formParamsCopy = _.cloneDeep(formParams)
    formParamsCopy?.map((item, index) => {
      item.key = index
      return null
    })

    this.setState({
      requestHeaderData: formParamsCopy || [],
      rawJson: body,
    })

    // 认证类型为 自定义文件 的情况
    const {
      authType, advancedFileName, advancedCacheKey, expires,
    } = apiHttpAuthParam || {}
    if (authType === 'jar') {
      const tempExpires = expires && moment(expires, 'YYYY-MM-DD')
      this.dataSourceForm?.current?.setFieldsValue({ expires: tempExpires })

      this.setState({
        fileList: [{
          uid: Math.random(),
          name: advancedFileName,
          status: 'done',
        }],
        advancedCacheKey,
        advancedFileName,
      })
    }

    const ResultVariableName = []
    const parentVar = []
    expressionParamList?.map(item => {
      ResultVariableName.push({
        varName: item.name,
        varExpression: item.expression,
      })
      if (item.relationship === 0) {
        parentVar.push(item.name)
      }
      return null
    })

    this.setState({
      contentType, // 备存一份
      jsScript: jsScript || modelStr,
      // resExampleRawJson: responseRawJson,  // 默认查详情页面不显示 返回示例的内容
      resExampleRawJson: '',
      responseRawJsonTemp: responseRawJson, // 备份，用作保存时使用（编辑的时候不做任何修改）
    })

    const fieldObj = {
      taskName,
      httpRequestMethod,
      url,
      ResultVariableName: ResultVariableName?.length > 0 ? ResultVariableName : [{
        varName: undefined,
        varExpression: undefined,
      }],
      parentVar,
      tabSelectedVal: jsScript ? 'custom' : 'default',
      varRelationship: parentVar.length > 0 ? 'differentLevels' : 'sameLevel',
      bodyType: contentType,
      ...apiHttpAuthParam,
      ...apiHttpRequestBodyParam,
    }
    delete fieldObj.expires
    this.dataSourceForm?.current?.setFieldsValue(fieldObj)

    // const { id, isView } = this.props?.history?.location?.query || {};
    // (formData?.nodeId || formData?.isGoBack) && this.testData(true, body)

    setTimeout(() => {
      !formData?.isGoBack && formData?.nodeId && this.handlePreview(true)
      // 初始化 请求体Tab的dom
      this.setState({ activeTabKey: '3' }, () => {
        this.setState({ activeTabKey: '1' })
      })
    }, 10)
    setTimeout(() => {
      // !formData?.isGoBack && formData?.nodeId && this.handlePreview()
      // 等第一屏渲染完成再去让第三、第四部的页面显示出来
      this.props.isShowLastPageFn()
    }, 2000)
  }

  // 编辑参数按钮回调
  onEditClick = (record) => {
    if (this.state.editingKey || this.state.editingKey === 0) {
      message.warning('请先完成当前参数的编辑')
      return
    }
    this.tableData?.current?.setFieldsValue(record)
    this.setState({
      editingKey: record.key,
    })
  }

  // 删除参数按钮回调
  onDelClick = (record) => {
    const arr = []
    this.state.requestHeaderData.map((item) => {
      if (item.key !== record.key) {
        arr.push(item)
      }
      return null
    })
    // 删除时按顺序重置key
    arr.map((item, index) => {
      item.key = index
      return null
    })
    this.setState({
      requestHeaderData: arr,
      editingKey: undefined,
    })
  }

  // 保存参数修改
  onFieldSaveClick = () => {
    this.tableData.current.validateFields().then(values => {
      const { requestHeaderData, editingKey } = this.state
      const dataObj = requestHeaderData.find((item) => item.key === editingKey)
      dataObj.paramType = 0
      dataObj.paramName = values.paramName
      dataObj.paramPosition = values.paramPosition
      dataObj.paramAttribute = values.paramAttribute
      dataObj.paramDataType = values.paramDataType
      dataObj.paramValue = values.paramValue
      dataObj.paramDesc = values.paramDesc
      this.setState({
        editingKey: undefined,
        requestHeaderData: _.clone(requestHeaderData),
      })
    })
  }

  // 取消参数修改
  onFieldCancelClick = () => {
    const { requestHeaderData } = this.state
    this.setState({
      editingKey: undefined,
      requestHeaderData: _.clone(requestHeaderData),
    })
  }

  // 新增参数
  onAddClick = () => {
    if (this.state.editingKey || this.state.editingKey === 0) {
      message.warning('请先完成当前参数的编辑')
      return
    }
    const { requestHeaderData } = this.state
    // eslint-disable-next-line react/no-access-state-in-setstate
    const len = requestHeaderData?.length
    requestHeaderData.push({
      paramName: undefined,
      paramPosition: undefined,
      paramAttribute: undefined,
      paramDataType: undefined,
      paramValue: undefined,
      paramDesc: undefined,
      key: len,
    })
    this.tableData.current.resetFields()
    this.setState({
      editingKey: len,
      requestHeaderData: _.clone(requestHeaderData),
    })
  }

  // 接口测试
  testData = (isInit = false, resBody = '') => {
    const {
      editingKey, activeTabKey, advancedCacheKey, requestHeaderData, contentType,
    } = this.state

    if (editingKey || editingKey === 0) {
      this.tableData.current.validateFields()
      this.setState({
        activeTabKey: '2',
      }, () => {
        this.tableData.current.validateFields()
      })
      return null
    }

    // const headerParams = []
    // this.state.requestHeaderData?.map(item => {
    //   const obj = {
    //     name: item.fieldName,
    //     value: item.fieldValue,
    //   }
    //   headerParams.push(obj)
    //   return null
    // })

    const bodyRaw = this.objectParamsRef?.current?.getEditorValue() || ''
    const checkFiled = ['taskName', 'httpRequestMethod', 'url', 'authType', 'accessKey', 'accessSecret', 'advancedFilePath', 'expires', 'bodyType', 'advanceClassReference', 'advanceMethodName', 'accessToken']

    this.dataSourceForm.current.validateFields(checkFiled).then(values => {
      const {
        httpRequestMethod, url, authType, accessKey, accessSecret, accessToken, expires, bodyType, advanceClassReference, advanceMethodName, advancedFilePath,
      } = values

      this.setState({
        apiLoading: true,
      })

      this.props.dispatch({
        type: 'offlineHttpsApiCreate/queryTest',
        params: {
          httpRequestMethod,
          url,
          apiHttpAuthParam: {
            authType,
            accessKey,
            accessSecret,
            accessToken,
            expires: expires && `${moment(expires).format('YYYY-MM-DD')} 23:59:59` || undefined,
            advanceClassReference,
            advanceMethodName,
            advancedFilePath,
            advancedCacheKey,
          },
          // apiHttpRequestHeaderParam: {
          //   params: headerParams,
          // },
          apiHttpRequestBodyParam: {
            contentType: bodyType || contentType || 'application/x-www-form-urlencoded',
            body: bodyRaw || resBody,
            formParams: requestHeaderData,
          },
        },
        cb: (res) => {
          const { data: resData, msg = '服务端错误', status } = res || {}
          this.setState({
            apiLoading: false,
          })
          if (status === 200) {
            let resExampleRawJson
            try {
              resExampleRawJson = JSON.stringify(JSON.parse(resData?.responseBody))
              !isInit && message.success(msg || '请求成功')
            } catch (e) {
              message.error(resData?.responseBody)
              resExampleRawJson = ' ' // 此处值不能直接设为空字符串，组件不更新
            }
            this.setState({
              resExampleRawJson,
              fieldSuggestion: resData?.expressions || [],
            })
          } else {
            message.error(msg || '服务端错误')
          }
        },
      })
    }).catch(errorInfo => {
      // 提升用户体验，选中了认证必填项，但在其他tab页签，通过message.warn提示并切换tab页
      const {
        authType, advancedFilePath, accessKey, accessSecret, accessToken, advanceClassReference, advanceMethodName, expires,
      } = errorInfo?.values || {}
      if (activeTabKey !== '1' && authType !== 'noauth' && (!advancedFilePath || !accessKey || !accessSecret || !accessToken || !advanceClassReference || !advanceMethodName || !expires)) {
        message.warn('请完善必填项')
        this.setState({
          activeTabKey: '1',
        })
      }
    })
    return null
  }

  // 预览
  handlePreview = (initReq = false) => {
    const { resExampleRawJson, activeTabKey, responseRawJsonTemp, jsScript: staJsScript } = this.state
    const { formData } = this.props
    const { isView } = formData || {}

    const jsScript = initReq ? staJsScript : (this.customEditorRef?.current?.getEditorValue() || '')

    this.dataSourceForm.current.validateFields().then(values => {
      const {
        ResultVariableName, parentVar = [], tabSelectedVal,
      } = values

      const paramExpressionInfos = []
      if (tabSelectedVal === 'default') {
        ResultVariableName?.map((item) => {
          paramExpressionInfos.push({
            expression: item?.varExpression,
            name: item?.varName,
            relationship: parentVar?.indexOf(item?.varName) === -1 ? 1 : 0,
          })
          return null
        })
      }

      if ((jsScript === '' || jsScript === modelStr) && tabSelectedVal === 'custom') {
        message.warning('请输入自定义脚本')
        return null
      }

      if (isView) {
        this.setState({
          previewLoading: true,
        })
      } else {
        this.setState({
          tableViewLoading: true,
        })
      }

      this.props.dispatch({
        type: 'offlineHttpsApiCreate/queryPreview',
        params: {
          responseRawJson: resExampleRawJson || responseRawJsonTemp,
          expressionParamList: tabSelectedVal === 'default' ? paramExpressionInfos : [],
          jsScript: tabSelectedVal === 'custom' ? jsScript : '',
        },
        cb: (res) => {
          const { status, msg, data: dataRes = [] } = res || {}
          const tablePreviewColumn = []
          const tablePreview = []
          // 如果是编辑/查详情的时候，预览接口调完之后再取消loading
          isView && this.setState({
            previewLoading: false,
          })
          if (status === 200) {
            dataRes[0]
              && dataRes[0].map((item) => {
                tablePreviewColumn.push({
                  title: item,
                  dataIndex: item,
                  key: item,
                  width: 100,
                  render: (txt) => (<div className={styles.td_ellipse} title={txt}>{txt}</div>),
                })
                return null
              })

            dataRes.slice(1).map((item) => {
              const obj = {}
              dataRes[0].map((val, key) => {
                obj[val] = `${item[key]}` // + ''  为了容错，后端返回的值为 对象类型
                return null
              })
              tablePreview.push(obj)
              return null
            })
            this.setState({
              tablePreview,
              tablePreviewColumn,
              tablePreviewColumnArray: dataRes[0],
              tableViewLoading: false,
              previewSta: false,
            }, () => {
              const formDataTemp = {
                ...this.props.formData,
                tablePreviewColumnArray: dataRes[0],
              }
              this.props.setFormDataFn(formDataTemp)
            })
          } else {
            message.warning(msg || '预览失败')
            this.setState({
              tableViewLoading: false,
              previewSta: true,
            })
          }
        },
      })
      return null
    }).catch(errorInfo => {
      const {
        authType, advancedFilePath, accessKey, accessSecret, accessToken, advanceClassReference, advanceMethodName, expires,
      } = errorInfo?.values || {}
      if (activeTabKey !== '1' && authType !== 'noauth' && (!advancedFilePath || !accessKey || !accessSecret || !accessToken || !advanceClassReference || !advanceMethodName || !expires)) {
        message.warn('请完善必填项')
        this.setState({
          activeTabKey: '1',
        })
      }
    })
  }

  // 下一步按钮回调
  nextStep = () => {
    const {
      editingKey, tablePreviewColumnArray, requestHeaderData, advancedCacheKey, advancedFileName, resExampleRawJson, rawJson, contentType, responseRawJsonTemp,
    } = this.state

    const jsScript = this.customEditorRef?.current?.getEditorValue() || ''

    if (editingKey || editingKey === 0) {
      message.warning('请先完成当前参数的编辑')
      this.tableData.current.validateFields()
      this.setState({
        activeTabKey: '2',
      }, () => {
        this.tableData.current.validateFields()
      })
      return null
    }

    this.dataSourceForm.current.validateFields().then(
      values => {
        const formData = { tablePreviewColumnArray }
        const {
          taskName, httpRequestMethod, url, authType, accessKey, accessSecret, accessToken, expires, bodyType, advanceClassReference, advanceMethodName, advancedFilePath, tabSelectedVal, ResultVariableName, parentVar = [],
        } = values

        if ((jsScript === '' || jsScript === modelStr) && tabSelectedVal === 'custom') {
          message.warning('请输入自定义脚本')
          return null
        }

        // const headerParams = []
        // requestHeaderData?.map(item => {
        //   const obj = {
        //     name: item.fieldName,
        //     value: item.fieldValue,
        //   }
        //   headerParams.push(obj)
        //   return null
        // })
        // const bodyRaw = this.objectParamsRef?.current?.getEditorValue() || rawJson || ''
        const bodyRaw = this.objectParamsRef?.current?.getEditorValue() || ''

        const paramExpressionInfos = []
        if (tabSelectedVal === 'default') {
          ResultVariableName?.map((item, index) => {
            paramExpressionInfos.push({
              expression: item?.varExpression,
              name: item?.varName,
              relationship: parentVar?.indexOf(item?.varName) === -1 ? 1 : 0,
            })
            return null
          })
        }

        const formDataTemp = {
          ...this.props.formData,
          ...formData,
          taskName,
          responseRawJsonTemp,
          apiHttpRequest: {
            apiHttpAuthParam: {
              authType,
              accessKey,
              accessSecret,
              accessToken,
              expires: expires && `${moment(expires).format('YYYY-MM-DD')} 23:59:59` || null,
              advanceClassReference,
              advanceMethodName,
              advancedFilePath,
              advancedCacheKey,
              advancedFileName, // 保存上传的jar文件名，用于返显
            },
            // apiHttpRequestHeaderParam: {
            //   params: headerParams,
            // },
            apiHttpRequestBodyParam: {
              contentType: bodyType || contentType || 'application/x-www-form-urlencoded',
              body: bodyRaw,
              formParams: requestHeaderData,
            },
            httpRequestMethod,
            url,
          },
          previewExpressRequest: {
            jsScript,
            expressionParamList: paramExpressionInfos,
            responseRawJson: resExampleRawJson || responseRawJsonTemp,
          },
        }

        this.props.setFormDataFn(formDataTemp)

        this.props.changeStep(1)
        return null
      },
      error => {
        const errorItem = error.errorFields[0]
        if (errorItem) {
          if ((errorItem.errors[0] === '请输入key' && errorItem.name[0] === 'accessKey')
            || (errorItem.errors[0] === '请输入value' && errorItem.name[0] === 'accessSecret')
            || (errorItem.errors[0] === '请输入Token' && errorItem.name[0] === 'accessToken')
            || (errorItem.errors[0] === '请上传jar包' && errorItem.name[0] === 'advancedFilePath')
            || (errorItem.errors[0] === '请输入类名' && errorItem.name[0] === 'advanceClassReference')
            || (errorItem.errors[0] === '请输入方法名' && errorItem.name[0] === 'advanceMethodName')
            || (errorItem.errors[0] === '请输入变量有效期' && errorItem.name[0] === 'expires')
          ) {
            message.warn('请完善必填项')
            this.setState({ activeTabKey: '1' })
          }
        }
      },
    )
    return null
  }

  disabledDate = current => current && current < moment().subtract(1, 'days')

  render() {
    const { isView } = this.props?.formData || {}
    // const { viewDetailSta } = this.props
    const {
      headerColumns, requestHeaderData, activeTabKey, jsScript, rawJson, apiLoading, fieldSuggestion, resExampleRawJson, tablePreviewColumn, tablePreview, previewSta, tableViewLoading, fileList, diffEditorUpdate, previewLoading,
    } = this.state
    return (
      <div className={`${styles.data_source} ${isView ? styles.data_source_detail : ''} data_source_global`}>
        <Spin spinning={previewLoading}>

          <Form
            ref={this.dataSourceForm}
            labelCol={{ span: 2 }}
            wrapperCol={{ span: 10 }}
            initialValues={this.props.initialValues}
            autoComplete="off"
          >
            <Item>
              <div className={styles.column}>基础设置</div>
            </Item>
            <Item
              label="任务名称"
              name="taskName"
              rules={[
                { required: true, message: '请输入任务名称' },
                {
                  pattern: new RegExp(descRe.reg, 'g'),
                  message: descRe.text,
                }]}
            >
              <Input placeholder="请输入任务名称" disabled={isView} />
            </Item>
            <Item>
              <div className={styles.column}>后端服务接口</div>
            </Item>
            <Item
              label="请求方式"
              name="httpRequestMethod"
              rules={[{ required: true, message: '请选择请求方式' }]}
              initialValue="GET"
            >
              <Radio.Group disabled={isView}>
                <Radio value="GET">GET</Radio>
                <Radio value="POST">POST</Radio>
              </Radio.Group>
            </Item>
            <Item
              label="URL"
              name="url"
              rules={[
                { required: true, message: '请输入URL' },
                {
                  pattern: new RegExp(urlRe.reg, 'g'),
                  message: urlRe.text,
                },
                {
                  pattern: new RegExp(urlLenRe.reg, 'g'),
                  message: urlLenRe.text,
                },
              ]}
            >
              <Input disabled={isView} placeholder="请输入URL" />
            </Item>
            <Item wrapperCol={{ span: 24 }}>
              <Tabs
                defaultActiveKey="1"
                activeKey={activeTabKey}
                onChange={(e) => {
                  this.setState({ activeTabKey: e })
                  e === '3' && this.handleToggleAside()
                }}
              >
                <TabPane tab="认证" key="1">
                  <Item
                    // labelCol={{ span: 4 }}
                    wrapperCol={{ span: 12 }}
                  >
                    <Item
                      labelCol={{ span: 4 }}
                      wrapperCol={{ span: 20 }}
                      label="类型"
                      name="authType"
                      rules={[{ required: true, message: '请选择认证类型' }]}
                      initialValue="noauth"
                    >
                      <Select
                        disabled={isView}
                        placeholder="请选择认证类型"
                      >
                        <Option value="noauth">无</Option>
                        <Option value="sign">API密钥</Option>
                        <Option value="token">Token令牌</Option>
                        <Option value="jar">自定义认证</Option>
                      </Select>
                    </Item>
                    <Item shouldUpdate noStyle>
                      {(form) => form.getFieldValue('authType') === 'sign' && (
                        <>
                          <Item
                            labelCol={{ span: 4 }}
                            wrapperCol={{ span: 20 }}
                            label="key"
                            name="accessKey"
                            rules={[
                              { required: true, message: '请输入key' },
                              {
                                pattern: new RegExp(lenRe.reg, 'g'),
                                message: lenRe.text,
                              },
                            ]}
                          >
                            <Input disabled={isView} placeholder="请输入key" />
                          </Item>
                          <Item
                            labelCol={{ span: 4 }}
                            wrapperCol={{ span: 20 }}
                            label="value"
                            name="accessSecret"
                            rules={[
                              { required: true, message: '请输入value' },
                              {
                                pattern: new RegExp(lenRe.reg, 'g'),
                                message: lenRe.text,
                              },
                            ]}
                          >
                            <Input disabled={isView} placeholder="请输入value" />
                          </Item>
                        </>
                      )}
                    </Item>
                    <Item shouldUpdate noStyle>
                      {(form) => form.getFieldValue('authType') === 'token' && (
                        <Item
                          labelCol={{ span: 4 }}
                          wrapperCol={{ span: 20 }}
                          label="Token"
                          name="accessToken"
                          rules={[
                            { required: true, message: '请输入Token' },
                            {
                              pattern: new RegExp(tokenLenRe.reg, 'g'),
                              message: tokenLenRe.text,
                            },
                          ]}
                        >
                          <Input disabled={isView} placeholder="请输入Token" />
                        </Item>
                      )}
                    </Item>
                    <Item shouldUpdate noStyle>
                      {(form) => form.getFieldValue('authType') === 'jar' && (
                        <>
                          <Item
                            wrapperCol={{ span: 24 }}
                            name="advancedFilePath"
                            rules={[{ required: true, message: '请上传jar包' }]}
                          >
                            <Dragger
                              disabled={isView}
                              name="file"
                              // multiple={false}
                              accept=".jar"
                              maxCount={1}
                              action={`${SUAN_PAN}/api/v1/integration/api/http/uploadJar`}
                              headers={{ 'X-Project-Id': getProjectId() }}
                              fileList={fileList}
                              onChange={(info) => {
                                if (info.file.status !== 'uploading') {
                                  // console.log(info.file, info.fileList);
                                }
                                if (info.file.status === 'done') {
                                  const res = info.file.response
                                  if (res.status === 200) {
                                    message.success(`${info.file.name} 上传成功`)
                                    this.dataSourceForm?.current?.setFieldsValue({ advancedFilePath: info?.file?.response?.data?.filePath })
                                    const advancedCacheKey = info?.file?.response?.data?.cacheKey
                                    const advancedFileName = info?.file?.name || ''
                                    this.setState({
                                      advancedCacheKey,
                                      advancedFileName,
                                    })
                                  } else {
                                    message.warning(res.msg, 3)
                                    info.file.status = 'error'
                                    info.file.response = res.msg || '上传错误'
                                    info.fileList.find((item) => item.uid === info.file.uid).status = 'error'
                                  }
                                } else if (info.file.status === 'error') {
                                  message.error(`${info.file.name} 上传失败.`)
                                }
                                if (info.file.status === 'removed') {
                                  this.dataSourceForm?.current?.setFieldsValue({ advancedFilePath: '' })
                                }

                                this.setState({
                                  fileList: info?.fileList || [],
                                })
                              }}
                              onRemove={() => {
                                this.dataSourceForm?.current?.setFieldsValue({ advancedFilePath: '' })
                              }}
                              style={{ height: '200px' }}
                            >
                              <p className="ant-upload-drag-icon">
                                <i className="iconfont icon-cunchu" />
                              </p>
                              <p className="ant-upload-text">将文件拖拽至此，或单击直接上传</p>
                              <p className="ant-upload-hint">支持扩展名：jar</p>
                            </Dragger>
                          </Item>
                          <Item
                            labelCol={{ span: 4 }}
                            wrapperCol={{ span: 20 }}
                            label="类名"
                            name="advanceClassReference"
                            rules={[
                              { required: true, message: '请输入类名' },
                              {
                                pattern: new RegExp(lenRe.reg, 'g'),
                                message: lenRe.text,
                              },
                            ]}
                          >
                            <Input disabled={isView} placeholder="请输入类名" />
                          </Item>
                          <Item
                            labelCol={{ span: 4 }}
                            wrapperCol={{ span: 20 }}
                            label="方法名"
                            name="advanceMethodName"
                            rules={[
                              { required: true, message: '请输入方法名' },
                              {
                                pattern: new RegExp(lenRe.reg, 'g'),
                                message: lenRe.text,
                              },
                            ]}
                          >
                            <Input disabled={isView} placeholder="请输入方法名" />
                          </Item>
                          <Item
                            labelCol={{ span: 4 }}
                            wrapperCol={{ span: 20 }}
                            label="变量有效期"
                            name="expires"
                            rules={[{ required: true, message: '请输入变量有效期' }]}
                          >
                            <DatePicker
                              disabled={isView}
                              disabledDate={this.disabledDate}
                              // value={beginDay && moment(beginDay, 'YYYY-MM-DD')}
                              // onChange={this.handleBeginDay}
                              placeholder="请输入变量有效期"
                              style={{ width: '100%' }}
                            />
                          </Item>
                        </>
                      )}
                    </Item>
                  </Item>
                </TabPane>
                {/* <TabPane tab="请求头" key="2"> */}
                {/*  <Item wrapperCol={{ span: 24 }}> */}
                {/*    <Form ref={this.tableData} component={false}> */}
                {/*      <ProTable */}
                {/*        rowKey={() => (Math.random())} */}
                {/*        loading={false} */}
                {/*        showQuickJumper={false} */}
                {/*        showSizeChanger={false} */}
                {/*        pagination={false} */}
                {/*        dataSource={requestHeaderData} */}
                {/*        components={{ */}
                {/*          body: { */}
                {/*            cell: EditableCell, */}
                {/*          }, */}
                {/*        }} */}
                {/*        columns={headerColumns.map(col => { */}
                {/*          if (!col.editable) { */}
                {/*            return col */}
                {/*          } */}
                {/*          return { */}
                {/*            ...col, */}
                {/*            onCell: (record) => ({ */}
                {/*              record, */}
                {/*              dataIndex: col.dataIndex, */}
                {/*              title: col.title, */}
                {/*              inputType: col.inputType, */}
                {/*              editing: this.state.editingKey === record.key, */}
                {/*            }), */}
                {/*          } */}
                {/*        })} */}
                {/*        scroll={{ y: 157 }} */}
                {/*      /> */}
                {/*      <div className={styles.add_item}> */}
                {/*        <Button */}
                {/*          disabled={isView} */}
                {/*          type="link" */}
                {/*          onClick={this.onAddClick} */}
                {/*        > */}
                {/*          <i className="iconfont icon-tianjia1" /> */}
                {/*          新增参数 */}
                {/*        </Button> */}
                {/*      </div> */}
                {/*    </Form> */}
                {/*  </Item> */}
                {/* </TabPane> */}
                <TabPane tab="请求体" key="3">
                  <Item
                    wrapperCol={{ span: 12 }}
                    label="类型"
                    name="bodyType"
                    rules={[{ required: true, message: '请选择请求体类型' }]}
                    initialValue="application/x-www-form-urlencoded"
                  >
                    <Select disabled={isView} onSelect={this.handleBodyType}>
                      <Option value="application/x-www-form-urlencoded">application/x-www-form-urlencoded</Option>
                      <Option value="application/json">application/json</Option>
                    </Select>
                  </Item>
                  <Item wrapperCol={{ span: 24 }}>
                    <Form ref={this.tableData} component={false}>
                      <ProTable
                        rowKey={() => (Math.random())}
                        loading={false}
                        showQuickJumper={false}
                        showSizeChanger={false}
                        pagination={false}
                        dataSource={requestHeaderData}
                        components={{
                          body: {
                            cell: EditableCell,
                          },
                        }}
                        columns={headerColumns.map(col => {
                          if (!col.editable) {
                            return col
                          }
                          return {
                            ...col,
                            onCell: (record) => ({
                              record,
                              dataIndex: col.dataIndex,
                              title: col.title,
                              inputType: col.inputType,
                              editing: this.state.editingKey === record.key,
                            }),
                          }
                        })}
                        // scroll={{ y: 157 }}
                        scroll={{ y: 180 }}
                      />
                      <div className={styles.add_item}>
                        <Button
                          disabled={isView}
                          type="link"
                          onClick={this.onAddClick}
                        >
                          <i className="iconfont icon-tianjia1" />
                          新增参数
                        </Button>
                      </div>
                    </Form>
                  </Item>
                  <Item shouldUpdate noStyle>
                    {(form) => form.getFieldValue('bodyType') === 'application/json' && (
                      <>
                        <div className={styles.tips}>支持变量pageNo、pageSize, 可赋予始值，如 {'key:${pageSize=0}'}</div>
                        <div className={styles.json_diff_editor}>
                          {
                            diffEditorUpdate && (
                              <CreateDiffEditor
                                readOnly={isView}
                                restData={rawJson || ''}
                                ref={this.objectParamsRef}
                                language="json"
                                theme={this.props?.themeValue === 'light' ? "vs" : "vs-dark"}
                                editorId={this.editorObjectEditId}
                              />
                            )
                          }
                        </div>
                      </>
                    )}
                  </Item>
                </TabPane>
              </Tabs>
            </Item>
            <Item wrapperCol={{ span: 12 }}>
              <Button
                disabled={isView}
                type="primary"
                loading={apiLoading}
                onClick={() => { this.testData() }}
              >
                接口测试
              </Button>
            </Item>
            <Item>
              <div className={styles.column}>返回示例</div>
            </Item>
            <Row gutter={16}>
              <Col span={12}>
                <Spin spinning={apiLoading}>
                  <div className={`${styles.api_bottom_out_example} ${styles.api_bottom_out_example_left}`}>
                    {
                      diffEditorUpdate && (
                        <CreateDiffEditor
                          restData={resExampleRawJson || ''}
                          language="json"
                          readOnly
                          theme={this.props?.themeValue === 'light' ? "vs" : "vs-dark"}
                          editorId={this.editorResonseId}
                          ref={this.returnRef}
                        />
                      )
                    }
                  </div>
                </Spin>
              </Col>
              <Col span={12}>
                <Item
                  noStyle
                  name="tabSelectedVal"
                  valuePropName="activeKey"
                  initialValue="default"
                >
                  <Tabs
                    destroyInactiveTabPane
                  >
                    <TabPane tab="默认" key="default" className={styles.tab_pane_height}>
                      <List
                        name="ResultVariableName"
                        initialValue={[{
                          varName: undefined,
                          varExpression: undefined,
                        }]}
                      >
                        {(fields, { add, remove }) => fields.map(({ key, name, ...restField }, index) => (
                          <Item
                            labelCol={index === 0 ? { span: 5 } : { span: 0 }}
                            wrapperCol={index === 0 ? { span: 19 } : { span: 19, offset: 5 }}
                            label={index === 0 ? (
                              <span>
                                结果变量名
                                <Popover
                                  content={
                                    <span>
                                      点击
                                      <span
                                        style={{ color: '#0084FF', cursor: 'pointer' }}
                                        onClick={() => {
                                          window.open(`${window.suanpan}Json.html`)
                                        }}
                                      >
                                        {' '}这里{' '}
                                      </span>
                                      查看Json解析说明
                                    </span>
                                  }
                                >
                                  <i className="iconfont icon-yiwentishi" />
                                </Popover>
                              </span>
                            ) : ''}
                            required
                            key={key}
                          >
                            <div className={styles.parameter_item}>
                              <Item
                                name={[name, 'varName']}
                                noStyle
                                style={{ display: 'inline-block', width: 'calc(50% - 8px)' }}
                                rules={[
                                  { required: true, message: '请输入结果变量名' },
                                  {
                                    pattern: new RegExp(lenRe.reg, 'g'),
                                    message: lenRe.text,
                                  },
                                ]}
                              >
                                <Input disabled={isView} placeholder="请输入结果变量名" />
                              </Item>
                              <span className={styles.equal_sign}> = </span>
                              <Item
                                name={[name, 'varExpression']}
                                noStyle
                                rules={[
                                  { required: true, message: '请输入结果表达式' },
                                  {
                                    pattern: new RegExp(lenRe.reg, 'g'),
                                    message: lenRe.text,
                                  },
                                ]}
                                style={{ display: 'inline-block', width: 'calc(50% - 8px)' }}
                              >
                                <AutoComplete
                                  disabled={isView}
                                  type="text"
                                  autoComplete="off"
                                  placeholder="请输入结果表达式"
                                >
                                  {
                                    fieldSuggestion.map(item => (
                                      <Option key={item} value={item}>
                                        {item}
                                      </Option>
                                    ))
                                  }
                                </AutoComplete>
                              </Item>
                              <div className={styles.item_btn_wrap}>
                                {
                                  fields.length - 1 === index && <i className={`iconfont icon-tianjia1 ${styles.add_sign} ${isView ? styles.disabled : ''}`} onClick={() => add()} />
                                }
                                {
                                  fields.length - 1 !== 0 && <i className={`iconfont icon-shanchu ${styles.del_sign} ${isView ? styles.disabled : ''}`} onClick={() => remove(name)} />
                                }
                              </div>
                            </div>
                          </Item>
                        ))}
                      </List>
                      <Item
                        labelCol={{ span: 5 }}
                        wrapperCol={{ span: 19 }}
                        label={
                          (
                            <span>
                              变量关系
                              <Popover
                                content="通过设置变量的层级关系，将有层级的json数据平展为数据库表，仅支持2种层级关系"
                              >
                                <i className="iconfont icon-yiwentishi" />
                              </Popover>
                            </span>
                          )
                        }
                        name="varRelationship"
                        rules={[{ required: true, message: '请选择变量关系' }]}
                        initialValue="sameLevel"
                      >
                        <Select disabled={isView}>
                          <Option key="sameLevel" value="sameLevel">
                            同级别
                          </Option>
                          <Option key="differentLevels" value="differentLevels">
                            不同级别
                          </Option>
                        </Select>
                      </Item>
                      <Item
                        noStyle
                        shouldUpdate
                      >
                        {(form) => {
                          const parentVarList = []
                          form.getFieldValue('ResultVariableName').map((item) => {
                            if (item && item.varName) {
                              parentVarList.push(item.varName)
                            }
                          })
                          return form.getFieldValue('varRelationship') === 'differentLevels' && (
                            <Item
                              name="parentVar"
                              wrapperCol={{ span: 20, offset: 5 }}
                              label=""
                              rules={[{ required: true, message: '请选择父级的变量' }]}
                            >
                              <Select
                                disabled={isView}
                                mode="multiple"
                                maxTagCount={4}
                                maxTagTextLength={7}
                                placeholder="请选择父级的变量"
                              >
                                {
                                  parentVarList.map(item => (
                                    <Option key={item} value={item}>
                                      {item}
                                    </Option>
                                  ))
                                }
                              </Select>
                            </Item>
                          )
                        }}
                      </Item>
                    </TabPane>
                    <TabPane tab="自定义" key="custom" className={styles.tab_pane_height}>
                      <div className={`${styles.api_bottom_out_example} ${styles.api_bottom_out_example_custom}`}>
                        {
                          diffEditorUpdate && (
                            <CreateDiffEditor
                              readOnly={isView}
                              language="javascript"
                              theme={this.props?.themeValue === 'light' ? "vs" : "vs-dark"}
                              editorId={this.editorJsEditId}
                              ref={this.customEditorRef}
                              restData={jsScript || ''}
                            />
                          )
                        }
                      </div>
                    </TabPane>
                  </Tabs>
                </Item>
                <Item
                  className={styles.btn_wrap}
                  wrapperCol={{ span: 20, offset: 5 }}
                  label=""
                  colon={false}
                  name="varRelationship"
                >
                  <Button type="primary" loading={tableViewLoading} onClick={() => { this.handlePreview() }}>预览</Button>
                </Item>
                <Item
                  labelCol={{ span: 5 }}
                  wrapperCol={{ span: 19 }}
                  label="计算结果"
                >
                  <ProTable
                    loading={tableViewLoading}
                    rowKey={() => (Math.random())}
                    columns={tablePreviewColumn}
                    dataSource={tablePreview}
                    scroll={{ x: true, y: 110 }}
                    pagination={false}
                  />
                </Item>
              </Col>
            </Row>
          </Form>
          {
            !isView && (
              <div className={styles.edit_footer}>
                {/* <Button */}
                {/*  className={styles.edit_btn} */}
                {/*  onClick={() => { history.push('/dataIntegrate/apiGather/http') }} */}
                {/* > */}
                {/*  取消 */}
                {/* </Button> */}
                <Button
                  className={styles.edit_btn}
                  type="primary"
                  onClick={this.nextStep}
                  disabled={previewSta}
                >
                  下一步
                </Button>
              </div>
            )
          }
        </Spin>
      </div>
    )
  }
}

// export default connect(({ offlineHttpsApiCreate }) => ({ ...offlineHttpsApiCreate }))(withRouter(DataSource))

class WrappedComponentRef extends PureComponent {
  render() {
    const { forwardedRef, ...rest } = this.props
    return (
      <DataSource ref={forwardedRef} {...rest} />
    )
  }
}

const IComponent = connect(({ global, offlineHttpsApiCreate }) => ({ themeValue: global.themeValue, ...offlineHttpsApiCreate }))(withRouter(WrappedComponentRef))

export default forwardRef((props, ref) => <IComponent {...props} forwardedRef={ref} />)
